#include <vtkSphereSource.h>
#include <vtkCubeSource.h>
#include <vtkConeSource.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkAssembly.h>
#include <vtkProperty.h>
#include <vtkNew.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorObserver.h>

int _main(int, char* []) {
    // Create a sphere
    vtkNew<vtkSphereSource> sphere;
    
    vtkNew<vtkPolyDataMapper> sphereMapper;
    sphereMapper->SetInputConnection(sphere->GetOutputPort());
    
    vtkNew<vtkActor> sphereActor;
    sphereActor->SetMapper(sphereMapper);
    sphereActor->SetOrigin(2, 1, 3);
    sphereActor->RotateY(6);
    sphereActor->SetPosition(2.25, 0, 0);
    sphereActor->GetProperty()->SetColor(1, 0, 1); // Magenta
    
    // Create a cube
    vtkNew<vtkCubeSource> cube;
    
    vtkNew<vtkPolyDataMapper> cubeMapper;
    cubeMapper->SetInputConnection(cube->GetOutputPort());
    
    vtkNew<vtkActor> cubeActor;
    cubeActor->SetMapper(cubeMapper);
    cubeActor->SetPosition(0.0, 0.25, 0);
    cubeActor->GetProperty()->SetColor(0, 0, 1); // Blue
    
    // Create a cone
    vtkNew<vtkConeSource> cone;
    
    vtkNew<vtkPolyDataMapper> coneMapper;
    coneMapper->SetInputConnection(cone->GetOutputPort());
    
    vtkNew<vtkActor> coneActor;
    coneActor->SetMapper(coneMapper);
    coneActor->SetPosition(0, 0, 0.25);
    coneActor->GetProperty()->SetColor(0, 1, 0); // Green
    
    // Create a cylinder
    vtkNew<vtkCylinderSource> cylinder;
    
    vtkNew<vtkPolyDataMapper> cylinderMapper;
    cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
    cylinderMapper->SetResolveCoincidentTopologyToPolygonOffset();
    
    vtkNew<vtkActor> cylinderActor;
    cylinderActor->SetMapper(cylinderMapper);
    cylinderActor->GetProperty()->SetColor(1, 0, 0); // Red
    
    // Create an assembly and add all parts
    vtkNew<vtkAssembly> assembly;
    assembly->AddPart(cylinderActor);
    assembly->AddPart(sphereActor);
    assembly->AddPart(cubeActor);
    assembly->AddPart(coneActor);
    assembly->SetOrigin(5, 10, 15);
    assembly->AddPosition(5, 0, 0);
    assembly->RotateX(15);
    
    vtkNew<vtkRenderer> renderer;
    renderer->AddActor(assembly);
    renderer->SetBackground(0.1, 0.2, 0.4);
    
    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(800, 600);
    renderWindow->SetWindowName("VTK Assembly Demo");
    
    vtkNew<vtkRenderWindowInteractor> interactor;
    interactor->SetRenderWindow(renderWindow);

    std::cout << "Interactor Style: " << interactor->GetInteractorStyle()->GetClassName() << std::endl;
    
    renderWindow->Render();
    interactor->Start();
    
    return EXIT_SUCCESS;
}